/*
 * File:    ACL.java
 * Created: 02-Feb-2008
 * Version: $Id$
 *
 * COPYRIGHT (C) 2008, Bitgate Software, LLC.  All Rights Reserved.
 *
 * software@bitgatesoftware.com
 */

package com.bitgate.util.service.acl;

import java.net.Socket;

import com.bitgate.util.config.Config;

/**
 * This is a singleton class that contains a list of known white, black, and neutrallisted IP addresses.  It contains functionality
 * to check an IP address based on the active {@link Socket} object passed to it.  The code here allows for matching using
 * Unix wildcard patterns.
 * 
 * @author kenji
 */
public class ACL
{
	private static final ACL _default = new ACL();
	private AddressVerifierInterface whitelistMatcher;
	private AddressVerifierInterface blacklistMatcher;
	
	private ACL() {
		String aclFilename = System.getProperty("acl.config");
		
		if (aclFilename == null) {
			aclFilename = "conf/defaults/acl.xml";
		}
		
		Config.getDefault().register(aclFilename, "acl");
		
		whitelistMatcher = new DefaultWhitelistVerifier();
		blacklistMatcher = new DefaultBlacklistVerifier();
	}
	
	/**
	 * Returns the singleton instance of this class.
	 * 
	 * @return <code>static final ACL</code> object.
	 */
	public static final ACL getDefault() {
		return _default;
	}
	
	/**
	 * Overrides the default whitelist handler.
	 * 
	 * @param avInterface {@link AddressVerifierInterface} class.
	 */
	public void setDefaultWhitelistHandler(AddressVerifierInterface avInterface) {
		whitelistMatcher = avInterface;
	}
	
	/**
	 * Overrides the default blacklist handler.
	 * 
	 * @param avInterface {@link AddressVerifierInterface} class.
	 */
	public void setDefaultBlacklistHandler(AddressVerifierInterface avInterface) {
		blacklistMatcher = avInterface;
	}
	
	/**
	 * Determines whether or not the passed {@link Socket} is whitelisted.
	 * 
	 * @param socket {@link Socket} containing the active connection.
	 * @return <code>true</code> if the socket is whitelisted, <code>false</code> otherwise.
	 */
	public boolean isWhitelisted(Socket socket) {
		return whitelistMatcher.matches(socket);
	}
	
	/**
	 * Determines whether or not the passed {@link Socket} is blacklisted.
	 * 
	 * @param socket {@link Socket} containing the active connection.
	 * @return <code>true</code> if the socket is blacklisted, <code>false</code> otherwise.
	 */
	public boolean isBlacklisted(Socket socket) {
		return blacklistMatcher.matches(socket);
	}
	
	/**
	 * Determines whether or not the passed {@link Socket} is neutrallisted.
	 * 
	 * @param socket {@link Socket} containing the active connection.
	 * @return <code>true</code> if the socket is neutrallisted, <code>false</code> otherwise.
	 */
	public boolean isNeutrallisted(Socket socket) {
		return (!isWhitelisted(socket) && !isBlacklisted(socket));
	}
}